tool
extends EditorPlugin


const ScnFuncTree = preload("res://addons/function_tree/util/node/FuncTree.tscn")

const FuncCore = preload("res://addons/function_tree/src/Core.gd")
const FuncStateMachine = preload("res://addons/function_tree/src/base/layer/custom/StateMachineRoot.gd")
const FuncSubSM = preload("res://addons/function_tree/src/base/function/statemachineroot/StateMachine.gd")

const RefreshPathScript = preload("res://addons/function_tree/util/generate/RefreshPathScript.gd")
const DelayHandle = preload("res://addons/function_tree/util/DelayHandle.gd")
const PathMapper = preload("res://addons/function_tree/util/PathMapper.gd")
const FuncTree = preload("res://addons/function_tree/util/node/FuncTree.gd")


var delayhandle = DelayHandle.new(self)
var path_mapper = PathMapper.new()

var func_tree : FuncTree 
var rps = RefreshPathScript.new()



#==================================================
#   内置方法
#==================================================
func _enter_tree():
	add_custom_type(
		"FunctionRoot", "Node", 
		preload("res://addons/function_tree/src/base/Root.gd")
		, get_editor_interface().get_base_control().get_icon("Node", "EditorIcons")
	)
	
	# 扫描脚本路径变动
	# 每 5 秒刷新一次，扫描脚本路径变动，并生成文件
#	rps.start(self, 5.0)
	
	func_tree = ScnFuncTree.instance()
	func_tree.rect_size.x = 150
	func_tree.icon = get_editor_interface() \
		.get_base_control() \
		.get_icon("Node", "EditorIcons")
	func_tree.connect("select_func_node", self, "add_node")


func _exit_tree():
	if func_tree:
		func_tree.queue_free()
	remove_custom_type("FunctionRoot")


func apply_changes():
	var list := get_editor_interface() \
		.get_selection() \
		.get_selected_nodes()
	if list.size() > 0:
		handles(list[0])
	else:
		make_visible(false)


func handles(object) -> bool:
	if object is Node:
		delayhandle.handles(object)
	return false


func make_visible(visible):
	if func_tree:
		# 显示面板
		if visible && !func_tree.is_inside_tree():
			add_control_to_container(
				CONTAINER_CANVAS_EDITOR_SIDE_LEFT 
				, func_tree
			)
			func_tree.show()
		# 隐藏面板
		elif !visible && func_tree.is_inside_tree():
			remove_control_from_container(
				CONTAINER_CANVAS_EDITOR_SIDE_LEFT
				, func_tree
			)
			func_tree.hide()
	return visible


func edit(object: Object):
	if object is FuncCore:
		var path = (object.get_script() as Script).resource_path
		func_tree.clear()
		func_tree.show()
		
		# Function 节点
		if PathMapper.is_function(object):
			if object is FuncSubSM:
				func_tree.add_path_item("res://addons/function_tree/src/base/function/statemachineroot/StateMachine.gd")
				func_tree.add_path_item("res://addons/function_tree/src/base/function/statemachineroot/State.gd")
				func_tree.add_path_item("res://addons/function_tree/src/custom/CustomFunction.gd")
			else:
				func_tree.add_path_item("res://addons/function_tree/src/custom/CustomFunction.gd")
				func_tree.add_path_item("res://addons/function_tree/src/base/Condition.gd")
		
		# 自定义 Layer 节点
		elif PathMapper.is_custom_layer(object):
			# 状态机
			if object is FuncStateMachine:
				func_tree.add_path_item("res://addons/function_tree/src/base/function/statemachineroot/StateMachine.gd")
				func_tree.add_path_item("res://addons/function_tree/src/base/function/statemachineroot/State.gd")
			# 其他
			else:
				func_tree.add_path_item("res://addons/function_tree/src/custom/CustomFunction.gd")
				func_tree.add_path_item("res://addons/function_tree/src/custom/SkillDataHandle.gd")
				func_tree.add_path_item("res://addons/function_tree/src/custom/SkillSignalHandle.gd")
				func_tree.add_path_item("res://addons/function_tree/src/base/function/actions/Action.gd")
				func_tree.add_path_item("res://addons/function_tree/src/base/function/events/Event.gd")
				func_tree.update_item(
					{"skills": {
						"Skill.gd": true,
						"Duration.gd": true,
					}}, 
					null, "res://addons/function_tree/src/base/function/"
				)
		
		# Layer 节点
		elif PathMapper.is_layer(object):
			if !func_tree.scan(path_mapper.map(path)):
				func_tree.hide() 
		
		# Category 节点
		elif PathMapper.is_standard(object):
			func_tree.scan("res://addons/function_tree/src/base/layer/standard/")
		elif PathMapper.is_custom(object):
			func_tree.add_path_item("res://addons/function_tree/src/custom/CustomLayer.gd")
			func_tree.add_scan("res://addons/function_tree/src/base/layer/custom/")
		
		# Root 节点
		elif PathMapper.is_root(object):
			func_tree.add_path_item("res://addons/function_tree/src/base/category/Standard.gd")
			func_tree.add_path_item("res://addons/function_tree/src/base/category/Custom.gd")
		else:
			func_tree.hide()
#			func_tree.scan(path_mapper.map(path))



#==================================================
#   自定义节点
#==================================================
##  添加节点 
## @path  脚本路径
func add_node(path: String) -> void:
	var list = get_editor_interface() \
		.get_selection() \
		.get_selected_nodes()
	if list.size() > 0:
		var node = Node.new()
		node.name = path.get_basename().get_file().capitalize().replace(" ", "")
		
		# 添加到场景树中（撤销/重做）
		var undo = get_undo_redo()
		undo.create_action("Add %s Node" % node.name)
		undo.add_do_method(
			self, "_add_to_tree", 
			node, list[0], path
		)
		undo.add_undo_method(
			self, "_remove_from_tree",
			node
		)
		undo.commit_action()
	else:
		print_debug("没有选中节点")


## 节点添加到树中
func _add_to_tree(node: Node, to, script_path: String):
	if not node.is_inside_tree():
		to.add_child(node, true)
		node.owner = get_editor_interface().get_edited_scene_root()
		node.set_script(load(script_path))


## 节点从树中删除
func _remove_from_tree(node: Node):
	if node.is_inside_tree():
		node.get_parent().remove_child(node)
